<template>
  <div class="sx-common-table">
    <el-table
      :data="data"
      :border="border"
      :stripe="stripe"
      :header-cell-style="headerCell"
      :height="height"
      :max-height="height ? '' : maxHeight"
      :row-class-name="tableRowClassName"
      @selection-change="handleSelectionChange"
      :span-method="arraySpanMethod"
    >
      <el-table-column
        v-if="isCheckbox"
        type="selection"
        width="55"
        align="center"
      >
      </el-table-column>
      <el-table-column
        v-if="isIndex"
        type="index"
        width="55"
        align="center"
        label="序号"
        :fixed="true"
      >
      </el-table-column>
      <slot></slot>
      <el-table-column
        v-for="(item, index) in columns"
        :prop="item.prop"
        :key="index"
        :label="item.label"
        :width="item.width || ''"
        :align="item.isLongText ? 'left' : item.align ? item.align : 'center'"
        :show-overflow-tooltip="item.isTextCut"
        :fixed="item.fixed"
      >
        <template slot-scope="scope">
          <template v-if="item.btn && item.btn.length">
            <div>
              <template v-for="(v, k) in item.btn">
                <el-button
                  :type="v.type || 'primary'"
                  size="small"
                  @click="btnClick(k, scope.row)"
                  :key="k"
                  >{{ v.name }}</el-button
                >
              </template>
            </div>
          </template>
          <template v-else-if="item.style === 'badge'">
            <el-badge
              :value="scope.row[item.prop]"
              :type="item.type"
              class="item"
            >
              <el-button
                size="small"
                :type="item.type"
                :plain="!scope.row[item.prop]"
                :disabled="!scope.row[item.prop]"
                @click="linkClick(item, scope.row)"
                >{{ item.label }}</el-button
              >
            </el-badge>
          </template>
          <template v-else-if="item.isLink">
            <div
              :class="getClass(item)"
              class="link"
              @click="linkClick(item, scope.row)"
            >
              {{ scope.row[item.prop] }}
            </div>
          </template>
          <template v-else>
            <div :class="getClass(item)">
              {{ scope.row[item.prop] }}
            </div>
          </template>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

<script>
export default {
  name: "SxCommonTable",
  props: {
    columns: {
      //表格列
      type: Array,
      default() {
        return [
          {
            label: "姓名",
            prop: "name",
            width: "",
            isLink: true,
            fixed: true,
            rowspan: true,
          },
          {
            label: "手机",
            prop: "phone",
            width: "",
          },
          {
            label: "余额",
            prop: "money",
            width: "",
            isPrice: true,
          },
          {
            label: "地址",
            prop: "address",
            isTextCut: true,
            isLongText: true,
          },
          {
            label: "角标",
            prop: "count",
            style: "badge",
            type: "success",
          },
          {
            label: "操作",
            width: "180px",
            btn: [{ name: "删除", type: "danger" }, { name: "编辑" }],
          },
        ];
      },
    },
    data: {
      //表格数据
      type: Array,
      default() {
        return [
          {
            name: "张三",
            phone: "15716022157",
            money: "99.57",
            address: "福建省福州市闽侯县海西科技园福建省福州市闽侯县海西科技园",
            count: 1,
          },
          {
            name: "张三",
            phone: "157160223331",
            money: "1573.22",
            address: "福建省福州市闽侯县海西科技园福建省福州市闽侯县海西科技园",
            count: 5,
          },
          {
            name: "王五",
            phone: "15716022332",
            money: "1577157513.22",
            address: "福建省福州市闽侯",
            count: "",
          },
          {
            name: "赵六",
            phone: "15716022333",
            money: "157113.22",
            address: "福建省福州市闽侯",
            count: 15,
          },
        ];
      },
    },
    isCheckbox: {
      //是否显示多选框
      type: Boolean,
      default() {
        return false;
      },
    },
    isIndex: {
      //是否显示序号
      type: Boolean,
      default() {
        return true;
      },
    },
    headerCell: {
      //表格头部样式自定义
      type: Object,
      default() {
        return {
          background: "#409eff",
          color: "#fff",
          textAlign: "center",
        };
      },
    },
    stripe: {
      //斑马纹
      type: Boolean,
      default() {
        return true;
      },
    },
    border: {
      //边框
      type: Boolean,
      default() {
        return true;
      },
    },
    height: {
      //表格高度
      type: [String, Number],
    },
    maxHeight: {
      type: [String, Number],
      default: 500,
    },
  },
  data() {
    return {
      //用来计算合并行
      spanArry: [],
      //checkbox选中的数据
      mulData: [],
    };
  },
  computed: {
    //需要合并行的列rowspan true合并
    th() {
      let x = [];
      this.columns.forEach((item, index) => {
        item.rowspan ? x.push(item.prop) : "";
      });
      return x;
    },
    //记录需要合并单元格列的 行索引，从第一行开始
    spanIndex() {
      let x = {};
      this.th.forEach((item) => {
        x[item] = 0;
      });
      return x; //初始从第一行开始 {prop1:0,prop2:0,...}
    },
  },
  watch: {
    data: {
      immediate: true,
      handler(val) {
        //合并行计算
        this.getRowSpan();
      },
    },
  },
  methods: {
    /**
     * 方法，外部调用，获取多选框选中的数据
     */
    getMulData() {
      console.log(this);
      return this.mulData;
    },
    /**
     * 按钮列回调事件
     */
    btnClick(index, row) {
      let obj = { index: index, row: row };
      console.log(obj);
      this.$emit("btnClick", obj);
    },
    /**
     * 单元格点击回调事件
     */
    linkClick(column, row) {
      let obj = { column: column, row: row };
      console.log(obj);
      this.$emit("linkClick", obj);
    },
    /**
     * 居中右对齐，长文本结尾省略号样式
     */
    getClass(obj) {
      let str = "";
      if (obj.isPrice) {
        str += " center-right";
      }
      if (obj.isTextCut) {
        str += " text-cut";
      }
      return str;
    },
    tableRowClassName({ row, rowIndex }) {
      return rowIndex % 2 ? "warning-row" : "";
    },
    /**
     * 多选框选中事件
     */
    handleSelectionChange(e) {
      this.mulData = e || [];
    },
    /**
     * 自定义合计列
     */
    // getSummaries(param) {
    //   console.log(param);
    //   const { columns, data } = param;
    //   const sums = [];
    //   columns.forEach((column, index) => {
    //     if (index === 0) {
    //       sums[index] = "总价";
    //       return;
    //     }
    //     console.log(
    //       this.columns,
    //       column.property,
    //       this.sumCols.some((ele) => ele === column.property)
    //     );
    //     if (
    //       this.sumCols.some((ele) => ele === column.property) ||
    //       !this.sumCols.length
    //     ) {
    //       //有科学计数法先去除,
    //       const values = data.map((item) =>
    //         Number((item[column.property] + "").replace(/,/g, ""))
    //       );
    //       if (!values.every((value) => isNaN(value))) {
    //         sums[index] = values.reduce((prev, curr) => {
    //           const value = Number(curr);
    //           if (!isNaN(value)) {
    //             return prev + curr;
    //           } else {
    //             return prev;
    //           }
    //         }, 0);
    //       } else {
    //         sums[index] = "-";
    //       }
    //     } else {
    //       sums[index] = "";
    //     }
    //   });

    //   return sums;
    // },
    /**
     * 获取数据相同的单元格个数
     */
    getRowSpan() {
      this.spanArry = []; //重置单元格合并的行数记录
      this.th.forEach((item) => {
        this.spanIndex[item] = 0;
      });
      this.data.forEach((item, index) => {
        if (index == 0) {
          let x = [];
          this.th.forEach((t) => {
            x.push(1);
          });
          this.spanArry.push(x); // [[2],[0]]代表第一行占两行，第二行0行
        } else {
          let s = [];
          //遍历所有需要合并单元格的列
          this.th.forEach((ele, eindex) => {
            //如果和上一条数据一样，spanIndex行索引+1
            if (item[ele] === this.data[index - 1][ele]) {
              this.spanArry[this.spanIndex[ele]][eindex]++;
              s.push(0);
            } else {
              //和上一条不一样，spanIndex行索引更新
              s.push(1);
              this.spanIndex[ele] = index;
            }
          });
          this.spanArry.push(s);
        }
      });
    },
    /**
     * 合并相同数据的单元格
     */
    arraySpanMethod({ row, column, rowIndex, columnIndex }) {
      for (let i = 0; i < this.th.length; i++) {
        if (column.property == this.th[i] && this.spanArry.length) {
          const _row = this.spanArry[rowIndex][i];
          const _col = _row > 0 ? 1 : 0;
          return {
            rowspan: _row,
            colspan: _col,
          };
        }
      }
    },
  },
};
</script>

<style>
.left {
  text-align: left;
}
.center {
  text-align: center;
}
.right {
  text-align: right;
}
.center-right {
  width: 60%;
  text-align: right;
  margin: 0 auto;
}
.text-cut {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.header-1 {
  background: #409eff;
}
.link {
  color: #409eff;
}
.link:hover {
  text-decoration: underline;
  cursor: pointer;
}
.el-table .warning-row {
  background: #e6f8ff;
}
.el-table .cell,
.el-table th div {
  overflow: visible;
}
.btn-grey {
  background: #f3f3f3;
  color: #999;
  border-color: #eee;
}
/* .el-table__footer .cell {
  width: 60%;
  text-align: right;
  margin: 0 auto;
}
.el-table__footer td:first-child .cell {
  width: 100%;
  text-align: center;
  margin: 0 auto;
} */
</style>
